package com.inspur.dgov.bsp.user.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.inspur.dgov.bsp.user.entity.PubOrgan;
import com.inspur.dgov.bsp.user.entity.PubUser;
import com.inspur.dgov.bsp.user.service.PubOrganService;
import com.inspur.dgov.bsp.user.service.PubUserService;
import com.inspur.dgov.bsp.user.service.TreeService;
import com.inspur.dgov.bsp.user.vo.OrganNode;
import com.inspur.dgov.bsp.user.vo.OrganVO;
import com.inspur.dgov.common.secure.dto.SecureUser;
import com.inspur.dgov.common.secure.utils.SecureUtil;
import com.inspur.dgov.common.tool.api.R;
import com.inspur.dgov.common.tool.constant.AppConstant;
import com.inspur.dgov.common.tool.utils.UniqueIdGenerator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 组织信息 前端控制器
 * </p>
 *
 * @author chiyupei
 * @since 2020-05-07
 */
@RestController
@RequestMapping("/organ")
@Api(value = "组织信息管理", tags = "组织信息接口")
public class PubOrganController {

    @Autowired
    private PubUserService pubUserService;

    @Autowired
    private TreeService treeService;

    @Autowired
    private PubOrganService pubOrganService;

    @Value("${tenant.default.id}")
    private String defaultTenantId;

    /**
     * 组织机构树
     */
    @GetMapping("/organTree")
    @ApiOperation(value = "组织机构树", notes = "组织机构树", position = 1)
    public R<List<OrganNode>> organTree() {
        //分别获取当前租户的区划和组织数据
        SecureUser curUser = SecureUtil.getUser();
        PubUser user = this.pubUserService.getById(curUser.getUserId());
        //区划数据根据当前用户所属区划获取
        //组织数据根据当前用户所属租户获取
        Long tenantId = user.getTenantId();
        PubOrgan organ = new PubOrgan();
        organ.setRegionId(user.getRegionId());
        if (!this.defaultTenantId.equals(tenantId.toString())) {
            organ.setTenantId(tenantId);
        }
        List<OrganNode> tree = this.treeService.organTree(organ);
        return R.data(tree);
    }

    /**
     * 组织机构分页列表
     *
     * @param nodeId
     * @param nodeType
     * @param query
     * @param page
     * @return
     */
    @PostMapping("/page")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "nodeId", value = "组织机构树节点ID", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "nodeType", value = "组织机构树节点类型", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "query", value = "查询条件", paramType = "query", dataType = "String")
    })
    @ApiOperation(value = "组织机构分页列表", notes = "传入组织机构树节点ID、组织机构树节点类型或查询条件", position = 2)
    public R<IPage<OrganVO>> page(@RequestParam(value="nodeId", required = false) String nodeId,
                                  @RequestParam(value="nodeType", required = false) String nodeType,
                                  @RequestParam(value="query", required = false) String query, Page page) {
        Map<String, Object> params = new HashMap<>();
        //组织数据根据当前用户所属租户获取
        SecureUser curUser = SecureUtil.getUser();
        String tenantId = curUser.getTenantId();

        if (!tenantId.equals(this.defaultTenantId)) {
            params.put("tenantId", tenantId);
        }
        params.put("query", query);

        if (StrUtil.isNotBlank(nodeId)) {
            //根据节点类型设置不同查询参数，1:上级组织ID 0:所属区划ID
            if ("0".equals(nodeType)) {
                params.put("regionId", nodeId);
            } else {
                params.put("parentId", nodeId);
            }
        }

        IPage<OrganVO> pages = this.pubOrganService.selectOrganPage(page, params);
        return R.data(pages);
    }

    /**
     * 唯一性校验
     *
     * @param value
     * @param id
     * @return
     */
    @PostMapping("/verifyUnique")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "value", value = "区划编码", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "id", value = "区划ID", paramType = "query", dataType = "String")
    })
    @ApiOperation(value = "组织唯一性校验", notes = "传入组织编码和组织ID", position = 3)
    public R verifyUnique(@RequestParam(value = "value", required = true) String value,
                          @RequestParam(value = "id", required = false) String id) {
        if (StrUtil.hasEmpty(value)) {
            return R.fail("接口调用不合法");
        }

        QueryWrapper<PubOrgan> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PubOrgan::getCode, value);
        if (StrUtil.isNotEmpty(id)) {
            queryWrapper.lambda().ne(PubOrgan::getId, id);
        }

        //查出满足条件的所有记录
        List<PubOrgan> list = this.pubOrganService.list(queryWrapper);
        if (ObjectUtil.isEmpty(list)) {
            return R.success("");
        }
        return R.fail("该组织编码已被使用");
    }

    /**
     * 新增组织机构
     *
     * @param organ
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "新增组织机构", notes = "传入组织机构信息", position = 4)
    public R add(@RequestBody PubOrgan organ) {
        SecureUser curUser = SecureUtil.getUser();
        LocalDateTime now = LocalDateTime.now();
        Long id = UniqueIdGenerator.generateId();
        organ.setId(id);
        organ.setTenantId(Long.valueOf(curUser.getTenantId()));
        organ.setCreator(Long.valueOf(curUser.getUserId()));
        organ.setCreateTime(now);
        organ.setStatus(AppConstant.DB_STATUS_NORMAL);
        boolean ret = this.pubOrganService.saveOrgan(organ);
        return R.status(ret);
    }

    /**
     * 更新组织机构
     *
     * @param organ
     * @return
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新组织机构", notes = "传入组织机构信息", position = 5)
    public R update(@RequestBody PubOrgan organ) {
        SecureUser curUser = SecureUtil.getUser();
        //判断是否更改父节点
        PubOrgan pubOrgan = this.pubOrganService.getById(organ.getId());
        Long newParentId = organ.getParentId();
        if (null != newParentId) {
            if (newParentId == pubOrgan.getId()) {
                return R.fail("上级组织机构不能选择自身");
            }
            //父节点变更
            if (!newParentId.equals(pubOrgan.getParentId())) {
                this.pubOrganService.moveOrgan(organ);
            }
        }
        LocalDateTime now = LocalDateTime.now();
        organ.setUpdator(Long.valueOf(curUser.getUserId()));
        organ.setUpdateTime(now);
        boolean ret = this.pubOrganService.updateById(organ);
        return R.status(ret);
    }

    /**
     * 删除组织机构
     * @param organ
     * @return
     */
    @PostMapping("/remove")
    @ApiOperation(value = "删除组织机构", notes = "传入组织机构信息", position = 6)
    public R remove(@RequestBody PubOrgan organ) {
        //检查是否有下级
        QueryWrapper<PubOrgan> organWrapper = new QueryWrapper<>();
        organWrapper.lambda().eq(PubOrgan::getParentId, organ.getId());
        int organCount = this.pubOrganService.count(organWrapper);
        if (organCount > 0) {
            return R.fail("存在下级组织机构，不能删除");
        }
        //检查组织机构下是否有用户
        QueryWrapper<PubUser> userWrapper = new QueryWrapper<>();
        userWrapper.lambda().eq(PubUser::getDirectOrganId, organ.getId());
        int userCount = this.pubUserService.count(userWrapper);
        if (userCount > 0) {
            return R.fail("该组织下存在用户，不能删除");
        }
        boolean ret = this.pubOrganService.deleteOrgan(organ);
        return R.status(ret);
    }

}
